/**
 * @author Ahammer
 * @date   2010 01
 * @update 2010 01 added progress bar support
 * @update 2011 01 added 16bit option
 */

/*
 * This file is part of Iqm.
 * Copyright (c) 2010-2011 Helmut Ahammer
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package op;

import java.awt.Point;
import java.awt.image.ColorModel;
import java.awt.image.DataBuffer;
import java.awt.image.DataBufferByte;
import java.awt.image.DataBufferFloat;
import java.awt.image.DataBufferUShort;
import java.awt.image.SampleModel;
import java.awt.image.WritableRaster;
import java.awt.image.renderable.ParameterBlock;
import java.util.Random;
import javax.media.jai.JAI;
import javax.media.jai.ParameterBlockJAI;
import javax.media.jai.PlanarImage;
import javax.media.jai.RasterFactory;
import javax.media.jai.RenderedOp;
import javax.media.jai.TiledImage;
import javax.media.jai.operator.IDFTDescriptor;

import main.Manager;


/**
 * This is the main image processing class
 * There exist two approaches:
 * A user defined JAI operator is just called 
 * or:
 * The actual processing is implemented in this class 
 */
public class IqmCreateImageOperator{ 

  public IqmCreateImageOperator() {
		  //WARNING: Don't declare fields here
		  //Fields declared here aren't thread safe!   
  }
  /**
   * 
   * @param ParametrBlockJAI pb
   */
  public Object run(ParameterBlockJAI pbJAI){
	    
	    Object ob = null;
	    //ob = JAI.create("IqmCrop".toLowerCase(), pb, null); 
	    
	    //PlanarImage pi = (PlanarImage) pbJAI.getSource(0);
	  	int width  = pbJAI.getIntParameter("Width");
	  	int height = pbJAI.getIntParameter("Height");
	  	int method = pbJAI.getIntParameter("Method");
	  	int gValue = pbJAI.getIntParameter("Const");	
	  	int omega  = pbJAI.getIntParameter("Omega");	
	  	int outbit = pbJAI.getIntParameter("OutBit");	
	  	
	  	//---------------------------------------------------------------------------------------------------------------------------	    
		//create image
	  	SampleModel sm    = null;
	  	WritableRaster wr = null;
	  	if (outbit == 0){ //8bit
		    sm = RasterFactory.createBandedSampleModel(DataBuffer.TYPE_BYTE, width, height, 1);  //1 banded sample model
	        byte[] byteArr = new byte[width*height];
		    DataBufferByte db = new DataBufferByte(byteArr, width*height);    
		    wr = RasterFactory.createWritableRaster(sm, db, new Point(0,0));
	  	}
	  	if (outbit == 1){ //16bit
		    sm = RasterFactory.createBandedSampleModel(DataBuffer.TYPE_USHORT, width, height, 1);  //1 banded sample model
	        short[] shortArr = new short[width*height];
		    DataBufferUShort db = new DataBufferUShort(shortArr, width*height);    
		    wr = RasterFactory.createWritableRaster(sm, db, new Point(0,0));
	  	}
	
	  	//---------------------------------------------------------------------------------------------------------------------------
	    if (method == 0){//generate random pixel values
		    Random generator = new Random();		
			for (int x = 0; x < width; x++){
				int proz = (x+1)*100 / width;
	   			Manager.setProgressBar(proz);
				for (int y = 0; y < height; y++){
				  	if (outbit == 0){ //8bit
				  		byte value = (byte)generator.nextInt(256);
				  		wr.setSample(x, y, 0, value); 
					}
				  	if (outbit == 1){ //16bit
				  		short value = (short)generator.nextInt(65536);
				  		wr.setSample(x, y, 0, value); 
					}

				}
			}
	    }
	    if (method == 1){//generate gauss distributed pixel values
		    Random generator = new Random();		
			for (int x = 0; x < width; x++){
				int proz = (x+1)*100 / width;
	   			Manager.setProgressBar(proz);
				for (int y = 0; y < height; y++){
				  	if (outbit == 0){ //8bit
				  		byte value = (byte)(generator.nextGaussian()*30 + 127);
				  		wr.setSample(x, y, 0, value); 
					}
				  	if (outbit == 1){ //16bit
				  		short value = (short)(generator.nextGaussian()*30 + 32767);
				  		wr.setSample(x, y, 0, value); 
					}			
				}
			}
	    }
	    if (method == 2){//generate constant grey value image		
			for (int x = 0; x < width; x++){
				int proz = (x+1)*100 / width;
	   			Manager.setProgressBar(proz);
				for (int y = 0; y < height; y++){
				  	if (outbit == 0){ //8bit
				  		byte value = (byte) gValue;
				  		wr.setSample(x, y, 0, value); 
					}
				  	if (outbit == 1){ //16bit
				  		short value = (short) gValue;
				  		wr.setSample(x, y, 0, value); 
					}								
				}
			}
	    }
	    if (method == 3){//generate sinus shaped image		
			for (int x = 0; x < width; x++){
				int proz = (x+1)*100 / width;
	   			Manager.setProgressBar(proz);
				for (int y = 0; y < height; y++){
					float fValue = (float) (Math.sin((float)x/(width-1)*omega*2*Math.PI));				
				  	if (outbit == 0){ //8bit
				  		fValue = (fValue + 1.0f)/2.0f *255.0f;
						wr.setSample(x, y, 0, (byte) fValue); 
					}
				  	if (outbit == 1){ //16bit
				  		fValue = (fValue + 1.0f)/2.0f *65535.0f;
						wr.setSample(x, y, 0, (short) fValue); 
					}	
				}
			}
	    }
	    if (method == 4){//generate cosinus shaped image
			for (int x = 0; x < width; x++){
				int proz = (x+1)*100 / width;
	   			Manager.setProgressBar(proz);
				for (int y = 0; y < height; y++){
					float fValue = (float) (Math.cos((float)x/(width-1)*omega*2*Math.PI));
				  	if (outbit == 0){ //8bit
				  		fValue = (fValue + 1.0f)/2.0f *255.0f;
						wr.setSample(x, y, 0, (byte) fValue); 
					}
				  	if (outbit == 1){ //16bit
				  		fValue = (fValue + 1.0f)/2.0f *65535.0f;
						wr.setSample(x, y, 0, (short) fValue); 
					}	
				}
			}
	    }	
	
		//create tiled images
	    ColorModel cm = PlanarImage.createColorModel(sm); //compatible color model
	    TiledImage ti = new TiledImage(0, 0, width, height, 0, 0, sm, cm);
	    ti.setData(wr);
	   
		 
//		//Change float to byte----------------------------------------------------
//		pb.removeSources();
//		pb.removeParameters();
//		pb.addSource(ti);
//		pb.add(DataBuffer.TYPE_BYTE);
//		ob = JAI.create("format", pb);
		  
	
		ob = ti;	  	  	
	  	//System.out.println("IqmCreateImage ob.getClass()" + ob.getClass());
		((PlanarImage) ob).setProperty("image_name", "Image");
		((PlanarImage) ob).setProperty("file_name", " ");
			
		return ob;
    }
}


